package com.pancm.datacollector.collector.impl;

import com.pancm.datacollector.collector.Collector;
import com.pancm.datacollector.collector.CollectorConfig;
import com.pancm.datacollector.collector.CollectorStatus;
import com.pancm.datacollector.queue.CollectedData;
import com.pancm.datacollector.queue.DataQueueManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * HTTP协议采集器实现
 */
public class HttpCollector implements Collector {
    private static final Logger LOG = LoggerFactory.getLogger(HttpCollector.class);
    
    private CollectorConfig config;
    private CollectorStatus status;
    private final RestTemplate restTemplate;
    private ScheduledExecutorService scheduler;
    private ScheduledFuture<?> collectTask;
    
    private String url;
    private HttpHeaders headers;
    private HttpMethod method;
    private Object body;
    
    @Autowired
    private DataQueueManager dataQueueManager;

    public HttpCollector(CollectorConfig config) {
        this.config = config;
        this.status = CollectorStatus.UNINIT;
        this.restTemplate = new RestTemplate();
        this.scheduler = Executors.newSingleThreadScheduledExecutor();
        
        // 初始化HTTP请求参数
        initHttpRequestParams();
    }
    
    /**
     * 初始化HTTP请求参数
     */
    @SuppressWarnings("unchecked")
    private void initHttpRequestParams() {
        this.url = String.format("http://%s:%d%s",
            config.getServerHost(),
            config.getServerPort(),
            config.getParameters().get("url"));

        this.headers = new HttpHeaders();
        Map<String, String> configHeaders = (Map<String, String>) config.getParameters().get("headers");
        if (configHeaders != null) {
            this.headers.setAll(configHeaders);
        }

        this.body = config.getParameters().get("body");
        
        this.method = HttpMethod.valueOf(
            ((String) config.getParameters().get("method")).toUpperCase()
        );
    }

    @Override
    public void start() throws Exception {
        LOG.info("启动HTTP采集器...");
        if (status == CollectorStatus.RUNNING) {
            LOG.warn("采集器已经在运行中");
            return;
        }

        try {
            // 启动定时采集任务
            collectTask = scheduler.scheduleAtFixedRate(
                () -> {
                    try {
                        collectToQueue();
                    } catch (Exception e) {
                        LOG.error("执行采集任务时发生错误", e);
                    }
                },
                0,
                config.getCollectInterval(),
                TimeUnit.SECONDS
            );
            
            status = CollectorStatus.RUNNING;
            LOG.info("HTTP采集器启动成功");
        } catch (Exception e) {
            status = CollectorStatus.ERROR;
            LOG.error("HTTP采集器启动失败", e);
            throw e;
        }
    }

    @Override
    public void stop() throws Exception {
        LOG.info("停止HTTP采集器...");
        if (status != CollectorStatus.RUNNING) {
            LOG.warn("采集器未在运行");
            return;
        }

        try {
            if (collectTask != null) {
                collectTask.cancel(true);
            }
            status = CollectorStatus.STOPPED;
            LOG.info("HTTP采集器已停止");
        } catch (Exception e) {
            status = CollectorStatus.ERROR;
            LOG.error("停止HTTP采集器时发生错误", e);
            throw e;
        }
    }

    @Override
    public void restart() throws Exception {
        LOG.info("重启HTTP采集器...");
        stop();
        start();
    }

    @Override
    @SuppressWarnings("unchecked")
    public HashMap<String, Object> collect() throws Exception {
        LOG.info("开始执行HTTP数据采集...");
        
        try {
            // 发送请求
            ResponseEntity<HashMap> response = restTemplate.exchange(
                url,
                method,
                new HttpEntity<>(body, headers),
                HashMap.class
            );

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                LOG.info("数据采集成功");
                
                // 创建采集数据对象
                CollectedData collectedData = new CollectedData(
                    "HTTP-" + config.getServerHost(),
                    response.getBody()
                );
                
                // 将数据放入队列
                if (!dataQueueManager.offer(collectedData)) {
                    LOG.warn("数据放入队列失败");
                }
                
                return response.getBody();
            } else {
                throw new Exception("HTTP请求失败，状态码: " + response.getStatusCode());
            }
        } catch (Exception e) {
            LOG.error("数据采集失败", e);
            throw e;
        }
    }

    @Override
    public void collectToQueue() throws Exception {
        LOG.info("开始执行HTTP数据采集并放入队列...");
        
        try {
            // 发送请求
            ResponseEntity<HashMap> response = restTemplate.exchange(
                url,
                method,
                new HttpEntity<>(body, headers),
                HashMap.class
            );

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                LOG.info("数据采集成功");
                
                // 创建采集数据对象
                CollectedData collectedData = new CollectedData(
                    "HTTP-" + config.getServerHost(),
                    response.getBody()
                );
                
                // 将数据放入队列
                if (!dataQueueManager.offer(collectedData)) {
                    throw new Exception("数据放入队列失败");
                }
                
                LOG.info("数据已成功放入处理队列");
            } else {
                throw new Exception("HTTP请求失败，状态码: " + response.getStatusCode());
            }
        } catch (Exception e) {
            LOG.error("数据采集或入队失败", e);
            throw e;
        }
    }

    @Override
    public CollectorStatus getStatus() {
        return status;
    }

    @Override
    public CollectorConfig getConfig() {
        return config;
    }

    @Override
    public void updateConfig(CollectorConfig config) throws Exception {
        LOG.info("更新采集器配置...");
        boolean needRestart = this.status == CollectorStatus.RUNNING;
        
        if (needRestart) {
            stop();
        }
        
        this.config = config;
        
        // 更新HTTP请求参数
        initHttpRequestParams();
        
        if (needRestart) {
            start();
        }
        
        LOG.info("采集器配置更新完成");
    }
} 